home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / amiga / asrc29k.lha / tcphdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-08  |  2.9 KB  |  130 lines

  1. #include "global.h"
  2. #include "mbuf.h"
  3. #include "tcp.h"
  4. #include "ip.h"
  5. #include "internet.h"
  6.  
  7. /* Convert TCP header in host format into mbuf ready for transmission,
  8.  * link in data (if any), and compute checksum
  9.  */
  10. struct mbuf *
  11. htontcp(tcph,data,ph)
  12. register struct tcp *tcph;
  13. struct mbuf *data;
  14. struct pseudo_header *ph;
  15. {
  16.     int16 hdrlen;
  17.     struct mbuf *bp;
  18.     register char *cp;
  19.     int16 csum;
  20.  
  21.     hdrlen = (tcph->mss != 0) ? TCPLEN + MSS_LENGTH : TCPLEN;
  22.     
  23.     if((bp = pushdown(data,hdrlen)) == NULLBUF){
  24.         free_p(data);
  25.         return NULLBUF;
  26.     }
  27.     cp = bp->data;
  28.     cp = put16(cp,tcph->source);
  29.     cp = put16(cp,tcph->dest);
  30.     cp = put32(cp,tcph->seq);
  31.     cp = put32(cp,tcph->ack);
  32.     *cp++ = hdrlen << 2;    /* Offset field */
  33.     *cp = 0;
  34.     if(tcph->flags.urg)
  35.         *cp |= 32;
  36.     if(tcph->flags.ack)
  37.         *cp |= 16;
  38.     if(tcph->flags.psh)
  39.         *cp |= 8;
  40.     if(tcph->flags.rst)
  41.         *cp |= 4;
  42.     if(tcph->flags.syn)
  43.         *cp |= 2;
  44.     if(tcph->flags.fin)
  45.         *cp |= 1;
  46.     cp++;
  47.     cp = put16(cp,tcph->wnd);
  48.     *cp++ = 0;    /* Zero out checksum field */
  49.     *cp++ = 0;
  50.     cp = put16(cp,tcph->up);
  51.  
  52.     if(tcph->mss != 0){
  53.         *cp++ = MSS_KIND;
  54.         *cp++ = MSS_LENGTH;
  55.         cp = put16(cp,tcph->mss);
  56.     }
  57.     csum = cksum(ph,bp,ph->length);
  58.     /* Fill checksum field */    
  59.     put16(&bp->data[16],csum);
  60.  
  61.     return bp;
  62. }
  63. /* Pull TCP header off mbuf */
  64. int
  65. ntohtcp(tcph,bpp)
  66. register struct tcp *tcph;
  67. struct mbuf **bpp;
  68. {
  69.     int16 hdrlen;
  70.     int16 i,optlen;
  71.     register int flags;
  72.     char hdrbuf[TCPLEN];
  73.  
  74.     i = pullup(bpp,hdrbuf,TCPLEN);
  75.     /* Note that the results will be garbage if the header is too short.
  76.      * We don't check for this because returned ICMP messages will be
  77.      * truncated, and we at least want to get the port numbers.
  78.      */
  79.     tcph->source = get16(&hdrbuf[0]);
  80.     tcph->dest = get16(&hdrbuf[2]);
  81.     tcph->seq = get32(&hdrbuf[4]);
  82.     tcph->ack = get32(&hdrbuf[8]);
  83.     hdrlen = (hdrbuf[12] & 0xf0) >> 2;
  84.     flags = hdrbuf[13];
  85.     tcph->flags.urg = flags & 32;
  86.     tcph->flags.ack = flags & 16;
  87.     tcph->flags.psh = flags & 8;
  88.     tcph->flags.rst = flags & 4;
  89.     tcph->flags.syn = flags & 2;
  90.     tcph->flags.fin = flags & 1;
  91.     tcph->wnd = get16(&hdrbuf[14]);
  92.     tcph->up = get16(&hdrbuf[18]);
  93.     tcph->mss = 0;
  94.  
  95.     /* Check for option field. Only space for one is allowed, but
  96.      * since there's only one TCP option (MSS) this isn't a problem
  97.      */
  98.     if(i < TCPLEN || hdrlen < TCPLEN)
  99.         return -1;    /* Header smaller than legal minimum */
  100.     if(hdrlen == TCPLEN)
  101.         return (int)hdrlen;    /* No options, all done */
  102.  
  103.     if(hdrlen > len_p(*bpp) + TCPLEN){
  104.         /* Remainder too short for options length specified */
  105.         return -1;
  106.     }
  107.     /* Process options */
  108.     for(i=TCPLEN; i < hdrlen;){
  109.         switch(pullchar(bpp)){
  110.         case EOL_KIND:
  111.             i++;
  112.             goto eol;    /* End of options list */
  113.         case NOOP_KIND:
  114.             i++;
  115.             break;
  116.         case MSS_KIND:
  117.             optlen = pullchar(bpp);
  118.             if(optlen == MSS_LENGTH)
  119.                 tcph->mss = pull16(bpp);
  120.             i += optlen;
  121.             break;
  122.         }
  123.     }
  124. eol:
  125.     /* Get rid of any padding */
  126.     if(i < hdrlen)
  127.         pullup(bpp,NULLCHAR,(int16)(hdrlen - i));
  128.     return (int)hdrlen;
  129. }
  130.